package com.example.springboot01.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.springboot01.config.ServiceException;
import com.example.springboot01.constant.Constants;
import com.example.springboot01.model.Account;
import com.example.springboot01.mapper.AccountMapper;
import com.example.springboot01.service.AccountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot01.utils.ParamsMatchUtils;
import com.example.springboot01.utils.UUIDUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zrd
 * @since 2022-05-16
 */
@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements AccountService {
    @Autowired
    AccountMapper accountMapper;
    @Autowired
    RedisTemplate redisTemplate;
    @Override
    public boolean save(Account account){
        //合规性校验

        validateRules(account);
        //唯一性校验,手机号码,邮件地址
        validateExistence(account,null);

        //补充属性，账户id
        account.setId(UUIDUtil.getUUID());
        //保存到数据库
        if(!super.save(account)){
            throw new ServiceException("保存失败");
        }

        //返回结果
        return true;
    }

    @Override
    public boolean updateById(Account account) {
        //合规性校验
        validateRules(account);
        //唯一性校验
        validateExistence(account,account.getId());
        //更新账户信息到数据库
        if(!super.updateById(account)){
            throw new ServiceException("修改账户信息失败");
        }
        redisTemplate.delete(Constants.REDIS_PREFIX_LOGIN_USER + account.getId());
        return true;
    }

    /**
     * 合规性校验
     * @param account  账户对象
     */
    private void validateRules(Account account) {
        if (!ParamsMatchUtils.userNameMatch(account.getUserName())){
            throw new ServiceException("账户名不合规，必须是4到16位（字母，数字，下划线，减号）");
        }
        if (account.getPassword() != null && !ParamsMatchUtils.passwordMatch(account.getPassword())){
            throw new ServiceException("账户密码不合规，必须只能包含字母和数字，须6-16位");
        }
        if (!ParamsMatchUtils.emailmatch(account.getEmail())){
            throw new ServiceException("账户邮箱不合规，必须只能包含字母和数字，例如2423643289@qq.com");
        }
        if (!ParamsMatchUtils.telephoneMatch(account.getTelephone())){
            throw new ServiceException("账户手机号不合规，必须只能包数字，须11位");
        }
        if (StringUtils.isNotEmpty(account.getGender()) && !"MAN".equals(account.getGender()) && !"WOMAN".equals(account.getGender())){
            throw new ServiceException("性别不合规，必须是MAN或者WOMAN");
        }
    }


    /**
     * 校验参数唯一性
     * @param account  账户对象
     * @param selfId   当前账户id
     */
    private void validateExistence(Account account, String selfId) {
        //手机唯一校验
        QueryWrapper<Account> wrapper = new QueryWrapper<Account>()
                .eq("telephone", account.getTelephone());
        if(StringUtils.isNotEmpty(selfId)){
            wrapper.ne("id",selfId);
        }
        if(accountMapper.selectCount(wrapper) >= 1){
            throw new ServiceException("手机号码已经存在");
        }

        //邮箱唯一校验
        wrapper = new QueryWrapper<Account>()
                .eq("email", account.getEmail());
        if(StringUtils.isNotEmpty(selfId)){
            wrapper.ne("id",selfId);
        }
        if(accountMapper.selectCount(wrapper) >= 1){
            throw new ServiceException("邮箱地址已经存在");
        }
    }

    @Override
    public List<Account> listByParams(Account account, Integer current, Integer size) {
        //创建条件构造器
        QueryWrapper<Account> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(account.getUserName())){
            wrapper.like("name",account.getUserName());
        }
        if (StringUtils.isNotEmpty(account.getNickName())){
            wrapper.like("nick_name",account.getNickName());
        }
        if (StringUtils.isNotEmpty(account.getTelephone())){
            wrapper.like("telephone",account.getTelephone());
        }
        if (StringUtils.isNotEmpty(account.getEmail())){
            wrapper.like("email",account.getEmail());
        }
        if (StringUtils.isNotEmpty(account.getImage())){
            wrapper.like("image",account.getImage());
        }
        wrapper.orderByAsc("telephone");

        //分页查询
        Page<Account> page = new Page<>(current,size);
        page = accountMapper.selectPage(page,wrapper);
        return page.getRecords();
    }

    @Override
    public String getUserIdByAdminNameAndPassword(String userName, String password) {
        Account account = getOne(new QueryWrapper<Account>()
                .eq("user_name",userName)
                .eq("password",password));
        if (account == null){
            throw new ServiceException("用户名或密码不正确");
        }
        return account.getId();
    }


    //获取账户
    @Override
    public Account getById(Serializable id) {
        //先从缓存取数
        Object object = redisTemplate.opsForValue().get(Constants.REDIS_PREFIX_LOGIN_USER + id);
        if (object != null){
            return (Account) object;
        }
        //如果缓存数据不存在，则从数据库取数，再更新缓存
        Account account =  super.getById(id);
        if (account != null){
            redisTemplate.opsForValue().set(Constants.REDIS_PREFIX_LOGIN_USER + id,account);
        }
        return account;
    }
    //删除用户
    @Override
    public boolean removeById(Serializable id) {
        boolean operSucc = super.removeById(id);
        redisTemplate.delete(Constants.REDIS_PREFIX_LOGIN_USER + id);
        return operSucc;
    }

}
